/*****
 * 界面操作展示类
 */
package com.fly.create;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.filechooser.FileFilter;

public class PatchCreator extends JFrame implements Observer
{
    private static final long serialVersionUID = -5589543870438580897L;
    
    // 界面组件
    JPanel panel = new JPanel();
    
    JLabel logInfoLabel = new JLabel("补丁文件日志信息:");
    
    JTextArea logInfoTextArea = new JTextArea();
    
    // 项目工程目录
    JLabel projDirLabel = new JLabel("项目工程目录: ");
    
    static JTextField projDirTextField = new JTextField(null, 45);
    
    JButton projDirBrowse = new JButton("请选择");
    
    // 补丁目录
    JLabel patchDirLabel = new JLabel("补丁文件存放目录: ");
    
    static JTextField patchDirTextField = new JTextField(null, 45);
    
    JButton patchDirBrowse = new JButton("请选择");
    
    // 创建
    JButton filter = new JButton("过滤补丁文件");
    
    JButton create = new JButton("创建补丁文件");
    
    JButton clear = new JButton("清除文件信息");
    
    TextUtil textUtil = TextUtil.getInstance();
    
    ConfigUtil configUtil;
    
    PatchCreator patchcreator = this;
    
    // 构造函数
    public PatchCreator()
    {
        // 加载图标
        URL imgURL = this.getClass().getResource("/resource/icon.gif");
        if (imgURL != null)
        {
            Image image = Toolkit.getDefaultToolkit().createImage(imgURL);
            setIconImage(image);
        }
        setTitle("补丁创建工具 V1.0");
        
        // 设置宽高
        setSize(900, 560);
        
        // 得到当前系统screenSize
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        
        // 得到当前frameSize
        Dimension frameSize = this.getSize();
        
        // 自适应处理
        if (frameSize.height > screenSize.height)
        {
            frameSize.height = screenSize.height;
        }
        if (frameSize.width > screenSize.width)
        {
            frameSize.width = screenSize.width;
        }
        setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
        
        addMenu();
        addButton();
        
        // 设定用户界面的外观
        try
        {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            SwingUtilities.updateComponentTreeUI(this);
        }
        catch (Exception e)
        {
        }
        setResizable(false);
        setVisible(true);
        addWindowListener(new WindowAdapter()
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        textUtil.addObserver(this);
        configUtil = ConfigUtil.getInstance();
        projDirTextField.setFocusable(false);
        patchDirTextField.setFocusable(false);
        
        // 加载默认配置
        try
        {
            configUtil.init();
            patchDirTextField.setText(configUtil.getConfig().getProperty("patchDir"));
            projDirTextField.setText(configUtil.getConfig().getProperty("projPath"));
        }
        catch (IOException e1)
        {
        }
    }
    
    // Menu set
    private void addMenu()
    {
        JMenuBar mb = new JMenuBar();
        // 一级菜单
        JMenu conf = new JMenu(" 文 件 ");
        // 子菜单
        
        // 子菜单
        JMenuItem loadDefault = new JMenuItem("使用默认");
        loadDefault.addActionListener((ActionEvent event) -> {
            try
            {
                configUtil.init();
                patchDirTextField.setText(configUtil.getConfig().getProperty("patchDir"));
                projDirTextField.setText(configUtil.getConfig().getProperty("projPath"));
                JOptionPane.showMessageDialog(panel, "加载默认配置文件 default.cfg 成功!", "恭喜", JOptionPane.INFORMATION_MESSAGE);
            }
            catch (Exception e1)
            {
                JOptionPane.showMessageDialog(panel, "加载默认配置文件 default.cfg 失败!", "Warning", JOptionPane.WARNING_MESSAGE);
            }
        });
        
        JMenuItem load = new JMenuItem("加载配置");
        load.addActionListener((ActionEvent event) -> {
            JFileChooser fc = new JFileChooser(new File("").getAbsoluteFile());
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            fc.setDialogTitle("请选择 cfg 文件");
            fc.setFileFilter(new FileFilter()
            {
                @Override
                public boolean accept(File f)
                {
                    if (f.isDirectory())
                    {
                        return true;
                    }
                    return (f.getName().toLowerCase().endsWith(".cfg"));
                }
                
                @Override
                public String getDescription()
                {
                    return ".cfg";
                }
            });
            if (fc.showOpenDialog(null) == 1)
            {
                return;
            }
            File file = fc.getSelectedFile();
            String fileName = file.getAbsolutePath();
            try
            {
                configUtil.init(file.getAbsolutePath());
                patchDirTextField.setText(configUtil.getConfig().getProperty("patchDir"));
                projDirTextField.setText(configUtil.getConfig().getProperty("projPath"));
                JOptionPane.showMessageDialog(panel, "加载配置文件 " + fileName + " 成功!", "恭喜", JOptionPane.INFORMATION_MESSAGE);
            }
            catch (Exception e)
            {
                JOptionPane.showMessageDialog(panel, "加载配置文件 " + fileName + " 失败!", "Warning", JOptionPane.WARNING_MESSAGE);
            }
        });
        
        JMenuItem save = new JMenuItem("保存配置");
        save.addActionListener((ActionEvent event) -> {
            JFileChooser fd = new JFileChooser(new File(" ").getAbsolutePath());
            fd.setDialogTitle("保存配置为");
            
            int i = 1001;
            String file = "default.cfg";
            while (new File(file).exists())
            {
                file = new StringBuffer("default_").append(String.valueOf(i).substring(1)).append(".cfg").toString();
                i++;
            }
            fd.setSelectedFile(new File(file.split("\\.")[0]));
            fd.setFileFilter(new FileFilter()
            {
                @Override
                public boolean accept(File file)
                {
                    return file.getName().endsWith(".cfg");
                }
                
                @Override
                public String getDescription()
                {
                    return ".cfg";
                }
            });
            
            if (fd.showSaveDialog(null) == 1)
            {
                return;
            }
            String fileName = fd.getSelectedFile().getAbsolutePath();
            if (!new File(fileName).exists())
            {
                fileName = fileName + ".cfg";
            }
            try
            {
                configUtil.saveToProperties(fileName);
                JOptionPane.showMessageDialog(panel, "保存当前配置到" + fileName + "成功!", "恭喜", JOptionPane.INFORMATION_MESSAGE);
            }
            catch (Exception e)
            {
                JOptionPane.showMessageDialog(panel, "保存当前配置到" + fileName + "失败!", "Error", JOptionPane.ERROR_MESSAGE);
            }
            
        });
        
        JMenuItem exit = new JMenuItem("退出");
        exit.addActionListener((ActionEvent event) -> System.exit(0));
        conf.add(loadDefault);
        conf.add(load);
        conf.addSeparator();
        conf.add(save);
        conf.addSeparator();
        conf.add(exit);
        mb.add(conf);
        
        JMenu help = new JMenu(" 帮 助 ");
        JMenuItem use = new JMenuItem("使用指南");
        use.addActionListener((ActionEvent event) -> JOptionPane.showMessageDialog(null,
            new StringBuffer("本工具支持工程目录下class、jsp、图片、css、html、jar等补丁文件创建").append("\n请按以下顺序操作：").append("\n 1. 拷贝SVN补丁文件信息。").append("\n 2. 填写项目工程目录,补丁文件保存目录。").append("\n 3. 过滤并创建补丁文件。"),
            "使用指南",
            JOptionPane.INFORMATION_MESSAGE));
        
        JMenuItem about = new JMenuItem("关于工具");
        about.addActionListener((ActionEvent event) -> JOptionPane.showMessageDialog(null, "Patch create 小工具，00fly 于2011年10月。\n", "关于本工具", JOptionPane.INFORMATION_MESSAGE));
        help.add(use);
        help.addSeparator();
        help.add(about);
        mb.add(help);
        setJMenuBar(mb);
    }
    
    // JButton set
    private void addButton()
    {
        panel.setLayout(null);
        getContentPane().add(panel);
        logInfoLabel.setBounds(20, 10, 120, 18);
        panel.add(logInfoLabel);
        String tip = new StringBuffer("请从SVN拷贝日志信息: ").append("1.SVN右键-->显示日志。 ").append("2.选中需要创建补丁的版本，右键--> 复制到剪贴板。 ").append("3.粘贴至此文本框。").toString();
        logInfoTextArea.setToolTipText(tip);
        logInfoTextArea.addCaretListener((CaretEvent caretevent) -> clear.setEnabled(logInfoTextArea.getText().length() > 0));
        JScrollPane scroll = new JScrollPane(logInfoTextArea);
        // 分别设置水平和垂直滚动条自动出现
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scroll.setBounds(20, 30, 850, 360);
        panel.add(scroll);
        projDirLabel.setBounds(30, 400, 120, 18);
        panel.add(projDirLabel);
        projDirTextField.setBounds(150, 400, 450, 20);
        panel.add(projDirTextField);
        projDirBrowse.setBounds(610, 400, 70, 24);
        projDirBrowse.setToolTipText("请选择当前工程的项目目录");
        projDirBrowse.addActionListener((ActionEvent event) -> {
            String text = projDirTextField.getText();
            if (text.length() == 0)
            {
                text = new File(" ").getAbsolutePath().trim();
            }
            String path = text;
            if (new File(text).getParentFile() != null)
            {
                path = new File(text).getParentFile().getAbsolutePath();
            }
            JFileChooser fc = new JFileChooser(path);
            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            fc.setDialogTitle("项目工程目录选择");
            if (fc.showOpenDialog(null) == 1)
            {
                return;
            }
            else
            {
                File f = fc.getSelectedFile();
                if (f.isDirectory() && f.getParentFile() != null)
                {
                    projDirTextField.setText(f.getAbsolutePath() + "\\");
                    create.setEnabled(!textUtil.getTextSet().isEmpty());
                }
                else
                {
                    projDirTextField.setText(null);
                }
            }
        });
        panel.add(projDirBrowse);
        
        patchDirLabel.setBounds(30, 430, 240, 18);
        panel.add(patchDirLabel);
        patchDirTextField.setBounds(150, 430, 450, 20);
        patchDirTextField.setText(new File(" ").getAbsolutePath().trim());
        panel.add(patchDirTextField);
        patchDirBrowse.setBounds(610, 430, 70, 24);
        patchDirBrowse.setToolTipText("请选择补丁存放目录");
        patchDirBrowse.addActionListener((ActionEvent event) -> {
            String path = patchDirTextField.getText();
            File xmlfile = new File(path);
            if (new File(patchDirTextField.getText()).getParentFile() != null)
            {
                xmlfile = new File(path).getParentFile();
            }
            JFileChooser fc = new JFileChooser(xmlfile);
            fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            fc.setDialogTitle("补丁存放目录选择");
            if (fc.showOpenDialog(null) == 1)
            {
                return;
            }
            File f = fc.getSelectedFile();
            if (f.isDirectory())
            {
                patchDirTextField.setText(f.getAbsolutePath() + "\\");
            }
        });
        panel.add(patchDirBrowse);
        
        filter.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                String[] textArea = logInfoTextArea.getText().split("\n");
                for (String it : textArea)
                {
                    textUtil.filter(it);
                }
                Set<String> list = textUtil.getTextSet();
                StringBuilder sb = new StringBuilder("补丁的文件数目： " + list.size());
                for (String text : list)
                {
                    sb.append("\n").append(text);
                }
                if (!list.isEmpty())
                {
                    sb.append("\n").append("---------------------------------------------------------------------------------------------");
                }
                create.setEnabled(!list.isEmpty() && !"".equals(projDirTextField.getText()));
                logInfoTextArea.setText(sb.toString());
            }
        });
        filter.setBounds(150, 460, 160, 30);
        panel.add(filter);
        
        create.setEnabled(false);
        create.setToolTipText("切记：生成补丁文件后一定要记得仔细对比，避免杯具发生。");
        create.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                if (!create.isEnabled())
                {
                    return;
                }
                if ("".equals(projDirTextField.getText()))
                {
                    JOptionPane.showMessageDialog(panel, "请选择当前工程的项目目录!", "提示", JOptionPane.WARNING_MESSAGE);
                    projDirBrowse.doClick();
                    return;
                }
                textUtil.setSourceDir(projDirTextField.getText());
                
                String[] t = projDirTextField.getText().split("\\\\");
                String projectName = t[t.length - 1] + DateUtil.getDateMark();
                
                String fileName = new StringBuilder(patchDirTextField.getText()).append(projectName).append("00").append("\\").toString();
                File f = new File(fileName);
                if (f.exists())
                {
                    if (JOptionPane.showConfirmDialog(panel, f.getAbsolutePath() + "\\ 目录已经存在，是否删除此目录下已经存在的文件以及说明文件？", "请确认", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION)
                    {
                        fileName = new StringBuilder(patchDirTextField.getText()).append(projectName).append("01").append("\\").toString();
                        f = new File(fileName);
                    }
                }
                textUtil.setTargetDir(fileName);
                textUtil.delAll(f.getAbsolutePath());
                textUtil.delReadMe(f.getParent());
                textUtil.process();
            }
        });
        create.setBounds(330, 460, 160, 30);
        panel.add(create);
        
        clear.setEnabled(false);
        clear.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                if (!clear.isEnabled())
                {
                    return;
                }
                
                if (!textUtil.getTextSet().isEmpty())
                {
                    if (JOptionPane.showConfirmDialog(panel, "上次补丁文件可能未创建，是否清除全部补丁文件信息？", "请确认", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION)
                    {
                        return;
                    }
                }
                textUtil.init();
                create.setEnabled(false);
                logInfoTextArea.setText(null);
            }
        });
        clear.setBounds(510, 460, 160, 30);
        panel.add(clear);
        
        JLabel link = new JLabel();
        link.setBounds(20, 480, 146, 18);
        link.setText("<html><a href='https://jq.qq.com/?_wv=1027&k=4AuWuZu'>Java 爱码少年</a></html>");
        link.setToolTipText("单击直达技术讨论群!~~");
        link.setCursor(new Cursor(Cursor.HAND_CURSOR));
        link.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                try
                {
                    Runtime.getRuntime().exec("cmd.exe /c start /min https://jq.qq.com/?_wv=1027^&k=4AuWuZu");
                }
                catch (Exception ex)
                {
                }
            }
        });
        panel.add(link);
        
    }
    
    /**
     * 观察者更新数据
     * 
     * @param obj
     * @param msg
     */
    @Override
    public void update(Observable obj, Object msg)
    {
        if (msg instanceof String)
        {
            logInfoTextArea.append(new StringBuffer("\n").append(msg).toString());
            if (((String)msg).contains("补丁文件创建结束"))
            {
                if (JOptionPane.showConfirmDialog(panel, "补丁文件创建结束，是否查看补丁文件信息？", "请确认", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                {
                    try
                    {
                        java.awt.Desktop.getDesktop().open(new File(patchDirTextField.getText()));
                    }
                    catch (IOException e)
                    {
                    }
                }
            }
        }
    }
    
    // Run
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> new PatchCreator());
    }
}
